package zh.demo.commons.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtils {
	public static List<Entry<String, String>> sortMap(final Map<String, String> map) {
		final List<Entry<String, String>> infos = new ArrayList<Entry<String, String>>(map.entrySet());
		// 重写集合的排序方法：按字母顺序
		Collections.sort(infos, new Comparator<Entry<String, String>>() {
			@Override
			public int compare(final Entry<String, String> o1, final Entry<String, String> o2) {
				return (o1.getKey().toString().compareTo(o2.getKey()));
			}
		});
		return infos;
	}

	public static String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return sb.toString();
	}

	public static String getP(String url, String str) {
		Object arr = null;
		Map<String, String> map = new HashMap<>();
		try {
			parseParameters(map, TruncateUrlPage(url), "UTF-8");
			if (map != null) {
				arr = map.get(str);
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return arr != null ? (String) arr : new String();
	}

	/**
	 * 去掉url中的路径，留下请求参数部分
	 * 
	 * @param strURL
	 *            url地址
	 * @return url请求参数部分
	 */
	private static String TruncateUrlPage(String strURL) {

		String strAllParam = null;
		String[] arrSplit = null;

		strURL = (strURL.trim());

		arrSplit = strURL.split("[?]");
		if (strURL.length() > 1) {
			if (arrSplit.length > 1) {
				if (arrSplit[1] != null) {
					strAllParam = arrSplit[1];
				}
			} else {
				strAllParam = strURL;
			}
		}
		return strAllParam;
	}

	public static boolean isExistByStart(String url) {
		Object arr = null;
		Map<String[], String[]> map = new HashMap<>();
		try {
			parseParameters(map, TruncateUrlPage(url), "UTF-8");
			if (map != null) {
				arr = map.get("start");
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return arr != null && (Integer) arr >= 0 ? true : false;
	}

	public static void parseParameters(Map map, String data, String encoding) throws UnsupportedEncodingException {
		if ((data == null) || (data.length() <= 0)) {
			return;
		}
		byte[] bytes = null;
		try {
			if (encoding == null)
				bytes = data.getBytes();
			else
				bytes = data.getBytes(encoding);
		} catch (UnsupportedEncodingException uee) {
		}
		parseParameters(map, bytes, encoding);
	}

	public static void parseParameters(Map map, byte[] data, String encoding) throws UnsupportedEncodingException {
		if ((data != null) && (data.length > 0)) {
			int ix = 0;
			int ox = 0;
			String key = null;
			String value = null;
			while (ix < data.length) {
				byte c = data[(ix++)];
				switch ((char) c) {
				case '&':
					value = new String(data, 0, ox, encoding);
					if (key != null) {
						putMapEntry(map, key, value);
						key = null;
					}
					ox = 0;
					break;
				case '=':
					if (key == null) {
						key = new String(data, 0, ox, encoding);
						ox = 0;
					} else {
						data[(ox++)] = c;
					}
					break;
				case '+':
					data[(ox++)] = 32;
					break;
				case '%':
					data[(ox++)] = (byte) ((convertHexDigit(data[(ix++)]) << 4) + convertHexDigit(data[(ix++)]));
					break;
				default:
					data[(ox++)] = c;
				}
			}
			if (key != null) {
				value = new String(data, 0, ox, encoding);
				putMapEntry(map, key, value);
			}
		}
	}

	private static void putMapEntry(Map map, String name, String value) {
		String newValues = null;
		String oldValues = (String) map.get(name);
		if (oldValues == null) {
			newValues = value;
		} else {
			System.arraycopy(oldValues, 0, newValues, 0, oldValues.length());
			newValues = value;
		}
		map.put(name, newValues);
	}

	private static byte convertHexDigit(byte b) {
		if ((b >= 48) && (b <= 57))
			return (byte) (b - 48);
		if ((b >= 97) && (b <= 102))
			return (byte) (b - 97 + 10);
		if ((b >= 65) && (b <= 70))
			return (byte) (b - 65 + 10);
		return 0;
	}

	public static boolean isError(String msg) {
		return msg.contains("HTTP error fetching URL") || msg.contains("Connection refused") || msg.contains("Read timed out") || msg.contains("connect timed out")
				|| msg.contains(" Unable to tunnel through proxy");
	}

	/**
	 * 将二进制转换成16进制
	 * 
	 * @param buf
	 * @return
	 */
	public static String parseByte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	/**
	 * 将16进制转换为二进制
	 * 
	 * @param hexStr
	 * @return
	 */
	public static byte[] parseHexStr2Byte(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

	public static boolean isNullOrEmpty(Object toTest) {
		return ((toTest == null) || (toTest.equals("null")) || (toTest.equals("")));
	}

	/**
	 * 判断是否为合法IP
	 * 
	 * @return the ip
	 */
	public static boolean isboolIp(String ipAddress) {
		String ip = "((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))";
		Pattern pattern = Pattern.compile(ip);
		Matcher matcher = pattern.matcher(ipAddress);
		return matcher.matches();
	}

	/**
	 * 从map中随机取得一个key
	 * 
	 * @param map
	 * @return
	 */
	public static <K, V> K getRandomKeyFromMap(Map<K, V> map) {
		int rn = getRandom().nextInt(map.size());
		int i = 0;
		for (K key : map.keySet()) {
			if (i == rn) {
				return key;
			}
			i++;
		}
		return null;
	}

	public static ThreadLocalRandom getRandom() {
		return ThreadLocalRandom.current();
	}

}
